﻿using System;
using System.Data.SqlClient;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System.Net.Http.Headers;
using System.Threading;

namespace DeepSeekDLL
{
    public class DeepSeekService
    {
        /// <summary>
        /// 【异步调用】连接数据库，调用 DeepSeek，并保存结果，返回获取到的结果
        /// </summary>
        /// <param name="connectionString">数据库链接语句</param>
        /// <param name="deepSeekKey">DeepSeek的key</param>
        /// <param name="deepSeekModel">DeepSeek的模型</param>
        /// <param name="chatText">发往DeepSeek的字符串</param>
        /// <param name="chatBackId">DeepSeek返回的字符串存储到指定表的id值</param>
        /// <param name="apiUrl">DeepSeek相关接口地址</param>
        /// <returns></returns>
        public async Task<string> ds1Sync(string connectionString, string deepSeekKey, string deepSeekModel, string chatText, int chatBackId, string apiUrl)
        {
            chatBackId = 0;
            //1、与 DeepSeek API 通信，发送请求并获取返回结果 
            string deepSeekResponse = await CallDeepSeekAPI(deepSeekKey, deepSeekModel, chatText, apiUrl); //使用 GetAwaiter().GetResult() 来等待异步任务

            //2、存入数据库
            var newId = SaveToDatabase(connectionString, chatText, deepSeekResponse, chatBackId);

            return deepSeekResponse;
        }

        /// <summary>
        /// 【同步调用】封装异步方法1
        /// </summary>
        /// <param name="connectionString"></param>
        /// <param name="deepSeekKey"></param>
        /// <param name="deepSeekModel"></param>
        /// <param name="chatText"></param>
        /// <param name="chatBackId"></param>
        /// <param name="apiUrl"></param>
        /// <returns></returns>
        public string ds1(string connectionString, string deepSeekKey, string deepSeekModel, string chatText, int chatBackId, string apiUrl)
        {
            // 使用 Task.Run 来异步执行并等待返回
            return Task.Run(async () =>
            {
                // 调用异步方法
                string deepSeekResponse = await ds1Sync(connectionString, deepSeekKey, deepSeekModel, chatText, chatBackId, apiUrl);
                // 检查返回值的长度，确保它不超过 4000
                if (deepSeekResponse.Length > 4000)
                {
                    deepSeekResponse = deepSeekResponse.Substring(0, 4000); // 截取前4000个字符
                }
                return deepSeekResponse;
            }).Result; // 使用 .Result 获取返回值
        }

        /// <summary>
        /// 【异步调用】连接数据库，调用 DeepSeek，更新对应id的结果字段值，返回获取到的结果
        /// </summary>
        /// <param name="connectionString">数据库链接语句</param>
        /// <param name="deepSeekKey">DeepSeek的key</param>
        /// <param name="deepSeekModel">DeepSeek的模型</param>
        /// <param name="chatText">发往DeepSeek的字符串</param>
        /// <param name="id">表数据id</param>
        /// <param name="apiUrl">DeepSeek相关接口地址</param>
        /// <param name="tableName">表名</param>
        /// <param name="fieldName">字段名</param>
        /// <returns></returns>
        public async Task<string> ds2Sync(string connectionString, string deepSeekKey, string deepSeekModel, string chatText, int id, string apiUrl, string tableName, string fieldName)
        {
            //1、与 DeepSeek API 通信，发送请求并获取返回结果 
            string deepSeekResult = await CallDeepSeekAPI(deepSeekKey, deepSeekModel, chatText, apiUrl);

            //2、更新数据库表数据
            UpdataToDatabase(connectionString, deepSeekResult, id, tableName, fieldName).GetAwaiter().GetResult();

            return deepSeekResult;
        }

        /// <summary>
        /// 【同步调用】封装异步方法2
        /// </summary>
        /// <param name="connectionString"></param>
        /// <param name="deepSeekKey"></param>
        /// <param name="deepSeekModel"></param>
        /// <param name="chatText"></param>
        /// <param name="id"></param>
        /// <param name="apiUrl"></param>
        /// <param name="tableName"></param>
        /// <param name="fieldName"></param>
        /// <returns></returns>
        public string ds2(string connectionString, string deepSeekKey, string deepSeekModel, string chatText, int id, string apiUrl, string tableName, string fieldName)
        {
            return Task.Run(async () =>
            {
                string deepSeekResult = await ds2Sync(connectionString, deepSeekKey, deepSeekModel, chatText, id, apiUrl, tableName, fieldName);
                // 检查返回值的长度，确保它不超过 4000
                if (deepSeekResult.Length > 4000)
                {
                    deepSeekResult = deepSeekResult.Substring(0, 4000); // 截取前4000个字符
                }
                return deepSeekResult;
            }).Result;
        }

        /// <summary>
        /// 调用 DeepSeek API 并获取返回内容
        /// </summary>
        /// <param name="deepSeekKey">数据库链接语句</param>
        /// <param name="deepSeekModel">DeepSeek的模型</param>
        /// <param name="chatText">发往DeepSeek的字符串</param>
        /// <returns></returns>
        private async Task<string> CallDeepSeekAPI(string deepSeekKey, string deepSeekModel, string chatText, string apiUrl)
        {
            using (var client = new HttpClient()) // 使用using确保正确释放资源
            {
                // 设置认证头
                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", deepSeekKey);

                // 构造请求参数
                var requestData = new
                {
                    model = deepSeekModel,//DeepSeek-R1。
                    messages = new[]
                     {
                       new
                       {
                           role = "user",
                           content = chatText // 获取用户输入
                       }
                   }
                };

                // 序列化请求内容
                var jsonContent = JsonConvert.SerializeObject(requestData);
                var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");

                try
                {
                    // 发送POST请求
                    var response = await client.PostAsync(apiUrl, content);

                    // 确保响应成功
                    response.EnsureSuccessStatusCode();

                    // 读取并解析响应
                    var responseContent = await response.Content.ReadAsStringAsync();
                    dynamic result = JsonConvert.DeserializeObject(responseContent);

                    // 显示结果
                    if (result.choices != null && result.choices.Count > 0)
                    {
                        return result.choices[0].message.content ?? "空内容";
                    }
                    else
                    {
                        return "未收到有效响应";
                    }
                }
                catch (HttpRequestException ex)
                {
                    // 显示请求错误信息
                    return "请求错误: " + ex.Message;
                }
                catch (JsonException ex)
                {
                    // 显示JSON解析错误信息
                    return "JSON解析错误: " + ex.Message;
                }
                catch (Exception ex)
                {
                    // 捕获其他异常
                    return "发生错误: " + ex.Message;
                }
            }
        }

        /// <summary>
        /// 将返回结果保存到数据库中，并赶回存储数据对应id
        /// </summary>
        /// <param name="connectionString">数据库连接语句</param>
        /// <param name="chatText1">发往DeepSeek的字符串</param>
        /// <param name="chatText2">DeepSeek返回的字符串</param>
        /// <param name="chatBackId">DeepSeek返回的字符串存储到指定表的id值（0-未收到返回字符串，其他-已收到返回字符串）</param>
        private async Task<int> SaveToDatabase(string connectionString, string chatText1, string chatText2, int chatBackId)
        {
            int newId = 0;
            chatBackId = chatText2 == null ? 0 : 1;
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                await connection.OpenAsync();
                string query = "INSERT INTO ewaichat(chatext1, chatext2, chatback) "
                             + "VALUES ( @chatext1, @chatext2, @chatback);"
                             + "SELECT SCOPE_IDENTITY();";  // 获取最新插入行的自增 ID

                using (SqlCommand cmd = new SqlCommand(query, connection))
                {
                    cmd.Parameters.AddWithValue("@chatext1", chatText1);
                    cmd.Parameters.AddWithValue("@chatext2", chatText2);
                    cmd.Parameters.AddWithValue("@chatback", chatBackId);

                    object result = cmd.ExecuteScalarAsync();
                    if (result != null)
                    {
                        newId = Convert.ToInt32(result);
                        Console.WriteLine("新增数据的ID是：" + newId);
                    }
                }
            }
            return newId;
        }


        /// <summary>
        /// 根据传递表名、字段名以及表id更新对应数据返回结果
        /// </summary>
        /// <param name="connectionString">数据库连接字符串</param>
        /// <param name="resultStr">获取到的返回结果</param>
        /// <param name="id">要更新的数据库表id</param>
        /// <param name="tableName">数据库表名</param>
        /// <param name="fieldName">存储返回结果的字段名</param>
        /// <returns></returns>
        private async Task<int> UpdataToDatabase(string connectionString, string resultStr, int id, string tableName, string fieldName)
        {
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                //异步打开链接
                await connection.OpenAsync();

                string query = "UPDATE " + tableName + " SET " + fieldName + " = @resultStr WHERE id = @id ;";

                using (SqlCommand cmd = new SqlCommand(query, connection))
                {
                    //使用参数化查询防止 SQL 注入
                    cmd.Parameters.AddWithValue("@resultStr", resultStr);
                    cmd.Parameters.AddWithValue("@id", id);

                    await cmd.ExecuteNonQueryAsync();

                    Console.WriteLine("更新数据的ID是：" + id);
                }
            }
            return id;
        }
    }
}
